/**
 * Jaxson ajax
 *
 * Copyright Remedy Interactive, licensed under Apache version 2 license:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0.html
 *
 * This notice must remain in all java source files.
 */

package org.jaxson.struts.encoder;


import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.Writer;
import java.util.Locale;

/**
 * Extension point for handing encoding of responses which 
 * consist of structured data.  Currently supported response
 * types are:
 * <ul>
 * 	<li>graphs (image/jpeg)<li>
 * 	<li>json   (application/json></li>
 *  <li>html   (text/html)<li>
 *  <li>xml    (text/xml)<li>
 * </ul>
 * 
 * @see org.jaxson.struts.encoder.ResponseContentType
 * 
 * @author Joe Maisel
 * 
 */
public abstract class ResponseEncoder
{
	private OutputStream output;
	private Writer writer;
	private Locale locale = Locale.getDefault();
	
	/**
	 * Encode a Serializable model to some format.
	 *  
	 * @throws EncodingException
	 */
	public abstract void encode( Serializable model ) throws EncodingException;
	
	/**
	 * Write output using either the OutputStream or PrintWriter. Preference is
	 * given to the OutputStream.
	 * 
	 * @throws IOException
	 */
	public void write( byte[] data ) throws IOException
	{
		if( output == null && writer == null )
			throw new IllegalStateException( "Neither an OutputStream or a Writer have been provided" );

		if( output != null )
		{
			output.write( data );
		}

		if( writer != null )
		{
			char[] c = new char[data.length];

			for( int i = 0; i < data.length; i++ )
			{
				c[i] = (char) data[i];
			}

			writer.write( c );
		}
	}

	/**
	 * @return the writer
	 */
	public Writer getWriter()
	{
		return writer;
	}

	/**
	 * @param writer
	 *            the writer to set
	 */
	public void setWriter( Writer writer )
	{
		this.writer = writer;
	}

	/**
	 * @return the output
	 */
	public OutputStream getOutputStream()
	{
		return output;
	}

	/**
	 * @param output
	 *            the output to set
	 */
	public void setOutputStream( OutputStream output )
	{
		this.output = output;
	}

	/**
	 * @return the locale
	 */
	public Locale getLocale()
	{
		return locale;
	}

	/**
	 * @param locale the locale to set
	 */
	public void setLocale( Locale locale )
	{
		this.locale = locale;
	}
}
